﻿/**
 *@description:
 *@file: rgb_video.cpp
 *@author: snow-tyan
 *@email: zziywang@163.com
 *@date: 2023-02-13 20:19:48
 *@copyright: 2018-2022 AiRiA. All rights reserved.
 */

#include <mygl/resource_manager.h>
#include <mygl/shader.h>
#include <mygl/static_renderer.h>
#include <mygl/texture2d.h>

#include <iostream>
#include <memory>
#include <vector>
#include <thread>

#include <GLFW/glfw3.h>

#ifndef PROJECT_ROOT
#define PROJECT_ROOT "/home/snow/OpenGLESProjects/MyOpenGLES_glfw"
#endif

using namespace mygl;

const std::string kProjectRoot = PROJECT_ROOT + std::string("/");
const std::string kResourcesRoot = kProjectRoot + "resources/videos/";
const std::string kShaderRoot = kProjectRoot + "07-InPractice/03-VideoRenderTest/rgb/";
const unsigned int kWindowWidth = 1280;
const unsigned int kWindowHeight = 720;
const char *kWindowName = "VideoRenderTestRgb";

void framebuffer_size_callback(GLFWwindow *window, int width, int height);
void processInput(GLFWwindow *window);

int main() {
  glfwInit();
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
  // glfwWindowHint(GLFW_REFRESH_RATE, 30);

  GLFWwindow *window =
      glfwCreateWindow(kWindowWidth, kWindowHeight, kWindowName, nullptr, nullptr);
  if (!window) {
    std::cout << "Failed to create GLFW window" << std::endl;
    glfwTerminate();
    return -1;
  }
  glfwMakeContextCurrent(window);
  glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
  glfwSwapInterval(1);  // Enable vsync

  if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
    std::cout << "Failed to initialize GLAD" << std::endl;
    return -1;
  }
  // print: gl info
  printf("GL_VENDOR: %s\n", glGetString(GL_VENDOR));  // 打印gl供应商
  printf("GL_VERSION: %s\n", glGetString(GL_VERSION));  // 打印gl版本，确定使用gles3
  int max_attributes;
  glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_attributes);  // 硬件支持的最大顶点属性数量
  printf("Max number of vertex attribute supported: %d\n", max_attributes);

  // Shader
  ResourceManager::LoadShader("rgb", kShaderRoot + "shader.vs",
                              kShaderRoot + "shader.fs");
  ResourceManager::LoadVideoTexture("table_wb", kResourcesRoot + "table_wb_1280x720.rgb",
                                    1280, 720);
  auto renderer = std::make_shared<StaticRenderer>(ResourceManager::GetShader("rgb"),
                                                   kWindowWidth, kWindowHeight);
  // render loop
  // -----------
  auto s = TimeNow(), e = TimeNow();
  size_t frame = 0;
  float fps = 30.0f;
  // auto timer = TimeNow();
  while (!glfwWindowShouldClose(window)) {
    processInput(window);
    glfwPollEvents();

    // render
    // ------
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // render container
    renderer->RenderVideo(ResourceManager::GetTexture("table_wb"), frame, fps,
                          ImageFormat::RGB, glm::vec2(0.0f, 0.0f),
                          glm::vec2(kWindowWidth, kWindowHeight));

    glfwSwapBuffers(window);
    if (frame % 30 == 0) {
      e = TimeNow();
      printf("render 30 frames cost time=%lf\n", CalcPerf(s, e));
      s = TimeNow();
    }
    ++frame;
  }
  ResourceManager::Clear();
  glfwTerminate();
  return 0;
}

void processInput(GLFWwindow *window) {
  if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
    glfwSetWindowShouldClose(window, true);
  }
}
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
  glViewport(0, 0, width, height);
}